package cn.echisan.springbootjwtdemo.filter;

import cn.echisan.springbootjwtdemo.entity.LoginUser;
import cn.echisan.springbootjwtdemo.utils.InputStreamHttpServletRequestWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 验证用户名密码正确后，生成一个token，并将token返回给客户端
 * 该类继承自UsernamePasswordAuthenticationFilter，重写了其中的2个方法 ,
 * attemptAuthentication：接收并解析用户凭证。
 * successfulAuthentication：用户成功登录后，这个方法会被调用，我们在这个方法里生成token并返回。
 * <p>
 * Created by echisan on 2018/6/23
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final ObjectMapper objectMapper;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, ObjectMapper objectMapper, String filterProcessesUrl) {
        setAuthenticationManager(authenticationManager);
        setFilterProcessesUrl(filterProcessesUrl);
        this.objectMapper = objectMapper;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        InputStreamHttpServletRequestWrapper inputStreamHttpServletRequestWrapper = new InputStreamHttpServletRequestWrapper(
                request);
        return super.attemptAuthentication(inputStreamHttpServletRequestWrapper, response);
    }

    @Override
    protected String obtainUsername(HttpServletRequest request) {
        try {
            LoginUser mLoginUser = objectMapper.readValue(request.getInputStream(), LoginUser.class);
            return mLoginUser.getUsername();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected String obtainPassword(HttpServletRequest request) {
        try {
            LoginUser mLoginUser = objectMapper.readValue(request.getInputStream(), LoginUser.class);
            return mLoginUser.getUsername();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
